#include <sys/socket.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <errno.h>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <iostream>
#include <string>
#include "../ConnectMsg.h"

using std::string;using std::cout;using std::endl;

string generateUsername()
{
	string str = "test";
	char buffer[10];
	sprintf(buffer,"%d",rand()%100000);
	str += (buffer);
	return str;
}

int generateMsg(unsigned char* buffer, ClientMsg msg)
{
	buffer[0] = msg;
	string usr = generateUsername();
	buffer[1] = usr.size();
	memcpy(buffer+2,usr.c_str(),usr.size());
	buffer[2+usr.size()] = 3;
	buffer[3+usr.size()] = 'x';
	buffer[4+usr.size()] = 'y';
	buffer[5+usr.size()] = 'z';

	return 6+usr.size();
}

void err_says(const char* msg)
{
	cout << msg << endl;
	cout << errno << endl;
}
void err_quit(const char* msg)
{
	cout << msg << endl;
	exit(EXIT_FAILURE);
}

int main(int argc, char **argv)
{
	srand(time(NULL));
	unsigned char buffer[1024];
	int sockfd, n;
	sockaddr_in servaddr;

	if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
		err_quit("socket error");

	memset(&servaddr, 0, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(19877);
	if (inet_pton(AF_INET, "127.0.0.1",&servaddr.sin_addr) <= 0)
		err_quit("inet_pton rror for ip address");

	if (connect(sockfd, (sockaddr *) &servaddr, sizeof(servaddr)) < 0)
		err_quit("connect failed");

	cout << "Connect success" << endl;
	int count = 0;
	
	timeval start, end;
	gettimeofday(&start, NULL);
	for (int i=0; i<10000000; ++i)
	{
		int index = generateMsg(buffer,LOGIN);
		int nSize = 0, readSize = 0;
		do 
		{
			if ( (readSize = write(sockfd,buffer+nSize, index-nSize)) == -1 )
			{
				cout << "write failed, errno:" << errno << endl;
				continue;	
			}
			nSize += readSize;
		}
		while (nSize < index);

		if (read(sockfd,buffer,1)<0)
			err_says("read error");
		else
		{
			if ((QueryResult)buffer[0] == SUCCESS)
				++count;
		}
	}
	gettimeofday(&end, NULL);
	long timeuse = 1000000 * (end.tv_sec-start.tv_sec) + end.tv_usec - start.tv_usec;
	cout << "Used time : " << timeuse/1000 << "ms"  << endl;
	cout << "Success Num. : " << count << endl;
	cout << "Exit" << endl;
	close(sockfd);
	return 0;   // To avoid Apache errors.
}
